home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol047 / sdir.asm < prev    next >
Encoding:
Assembly Source File  |  1987-01-11  |  16.7 KB  |  622 lines

  1.     TITLE   SDIR - SORTED DIRECTORY COMMAND, Version 2.1
  2.     PAGE    64,132                  ; JAN 1983
  3. COMMENT |
  4.     SDIR [d:][filename[.ext]] [options]
  5.      [filespec] same as for DIR command
  6.  
  7.      [options] * /A - List hidden files.
  8.            * /E - Without screen erase.
  9.            * /P - Pause when screen full.
  10.          /X - Sort by extension.
  11.          /S - Sort by size.
  12.          /D - Sort by date/time.
  13.          /N - Do not sort, original order.
  14.  
  15.        Default = *.* sorted by name.ext with screen erase.
  16.        * - Option may be combined with other options.
  17.  
  18.    This source file was created from an object file obtained
  19.  from Gene Plantz's BBS in Chicago. The original file name
  20.  was SD.HEX.  I then used DEBUG and CAPTURE to get the first
  21.  dis-assembly which  was then edited with WORDSTAR to create
  22.  a source that when assembled using MASM would duplicate the
  23.  original object file.
  24.    Comments have been added and I do hope they are helpful.
  25.  I have made several modifications to the first version and
  26.  am continuing to add comments.  This source file is an
  27.  excellent example for anyone wishing to learn 8086/8088
  28.  assembly language.  Use at your own risk and feel free to
  29.  share this file with your friends.
  30.    I certainly wish that John Chapman would publish his
  31.  source file.  His comments are sure to be more meaningful
  32.  than mine could ever be.  Some of the conversion routines
  33.  are very elegant, but difficult to understand.  As far as
  34.  I'm concerned, PRINTDD is magic.
  35.    Several modifications have been made.  They are:
  36.  
  37.     1. Filespecs are processed like DIR does.
  38.     2. No sort option was added. /N
  39.     3. Pause when screen full option added. /P
  40.     4. Number of files found is printed.
  41.  
  42.                     Ted Reuss
  43.                     Houston, TX
  44.  
  45.     SDIR Version 2.2  The GETFREE Subroutine was updated for DOS 2.0
  46.     April 1, 1983   by     Jack Y. Fong
  47.     Changes are denoted by "JYF" at the end of changed lines.
  48. |
  49.  
  50.     SUBTTL  EQUATES & STRUCTURES
  51.     PAGE
  52. IF1
  53. DOSCALL MACRO        FUNC,PARM1
  54. .xcref
  55. F_C =        FUNC
  56. IFNB <PARM1>
  57. IF F_C EQ 2 OR (F_C GE 4 AND F_C LE 6) OR F_C EQ 14 OR F_C EQ 46
  58.     MOV     DL,PARM1
  59. ELSE
  60.     MOV     DX,OFFSET PARM1
  61. ENDIF
  62. ENDIF
  63.     MOV    AH,FUNC
  64.     INT    21H
  65. .cref
  66.     ENDM
  67. ENDIF
  68. .SALL    ;supress all macro expansions
  69. ;    PC-DOS INTERRUPT 21H FUNCTION CODES
  70. ;
  71. @CHROUT EQU    2    ;display char in DL
  72. @KEYIN    EQU    8    ;kybd input w/o echo
  73. @STROUT EQU    9    ;print string terminated with $
  74. @CKEYIN EQU    12    ;clr kybd bufr & do inp.func in AL
  75. @SRCH1    EQU    17    ;search for first dir entry
  76. @SRCH2    EQU    18    ;search for next dir entry
  77. @GETDSK EQU    25    ;get default disk drive
  78. @SETDTA EQU    26    ;set disk transfer addr
  79. @FATAD2 EQU    28    ;get FAT of drive # in DL
  80. @PARSEF EQU 41        ;parse filename
  81. @GETDTE EQU 42        ;get system date
  82. @GETTME EQU 44        ;get system time
  83. @DSKFSP EQU 36H     ;get disk free space                JYF
  84. @GETVER EQU 30H     ;get version number                 JYF
  85.  
  86. CR  EQU     0DH     ;carriage return
  87. LF  EQU     0AH     ;line feed
  88. FCB_1        EQU     5CH     ;fcb for parameter 1
  89. PARAM_L EQU 80H     ;# characters in PARAM_B
  90. PARAM_B EQU 81H     ;DOS cmd parameter buffer.
  91.  
  92. ; PC-DOS packed date   <yyyyyyym mmmddddd>
  93. P_DTE        RECORD  P_YR:7,P_MO:4,P_DY:5
  94. ; PC-DOS packed time   <hhhhhmmm mmmsssss>
  95. P_TME        RECORD  P_HR:5,P_MI:6,P_2S:5
  96.  
  97. DIRNTRY STRUC            ;directory entry structure
  98. LNK DW        0        ;ptr to next entry
  99. NAM DB        8 DUP(0),'.' ;filename
  100. EXT DB        3 DUP(0) ;extension
  101. TME DW        0        ;time
  102. DTE    DW    0    ;date
  103. SZL    DW    0    ;low word of size
  104. SZH    DW    0    ;high word of size
  105. DIRNTRY ENDS
  106.  
  107.     SUBTTL    DATA AREA & INITIALIZATION
  108.     PAGE
  109. SDIR    SEGMENT PUBLIC 'CODE'
  110.     ASSUME    CS:SDIR,DS:SDIR,ES:SDIR
  111.     ORG    100H
  112. MAIN    PROC    FAR
  113.     JMP    STARTS
  114.  
  115. DIRLNK    DW    DIRBUF    ;ptr to next opening in DIRBUF
  116. C1LNK    DW    0    ;ptr to row 1, column 1
  117. C2LNK    DW    0    ;ptr to row 1, column 2
  118. NBRFILS DW    0    ;# of files or detail lines
  119. SRTFLG    DB    0    ;if = 0 then sort else no sort
  120. CLSFLG        DB        0        ;if = 0 then clear screen
  121. EXTFLG        DB        0        ;if <> 0 then sort by ext
  122. SIZFLG        DB        0        ;if <> 0 then sort by size
  123. DTEFLG        DB        0        ;if <> 0 then sort by date/time
  124. PSEFLG        DB        0        ;if <> 0 then pause if screen full
  125. LPERSCR EQU 25        ;Lines per screen
  126. LINCNT        DB        LPERSCR-4 ;Number of lines left
  127. PSEMSG        DB        'Strike a key when ready . . . $'
  128.  
  129. HDNG1        DB        'Capital PC Software Exchange /AEPXSDN/2.2 ' ;   JYF
  130.     DB        'DRIVE '
  131. HDRVE        DB        '@:    Date '
  132. D_MM        DW        '00'            ;Month
  133.     DB        '/'
  134. D_DD        DW        '00'            ;Day
  135.     DB        '/'
  136. D_YY        DW        '00'            ;Year
  137.     DB        '  Time '
  138. T_HH        DW        '00'            ;Hours
  139.     DB        ':'
  140. T_MM        DW        '00'            ;Minutes
  141.     DB        CR,LF
  142. CRLF    DB    CR,LF,'$'
  143. HDNG2    DB    'FILESPEC.EXT  BYTES-  --LAST CHANGE--$'
  144.     DB    8 DUP(' ')
  145. SPACES    DB    '$'
  146. HDNG3    DB    ' File(s)',CR,LF,'$'
  147.  
  148.     SUBTTL    DISK TRANSFER AREA & FREE SPACE ENTRY DEFS
  149.     PAGE
  150.  
  151. XFCB    DB    -1,7 DUP(0),11 DUP('?'),25 DUP(0)
  152. ATTRIB    EQU    XFCB+6        ;file attribute
  153. DRVNBR    EQU    ATTRIB+1    ;drive # (1=A, 2=B, etc.)
  154.  
  155. DTA    DB    40 DUP(0)    ;Disk Transfer Area used
  156. FILNAME EQU    DTA+8        ;by SRCHDIR for the
  157. FILTIME EQU    DTA+30        ;directory search.
  158. FILSIZE EQU    DTA+36
  159.  
  160. FREESPC DW    0        ;Free space entry.
  161.     DB    '*FREE SPACE*',4 DUP(0)
  162. LOSIZE    DW    0        ;of free space
  163. HISIZE    DW    0        ;of free space
  164.  
  165.     SUBTTL    MAIN PROGRAM SECTION
  166.     PAGE
  167. STARTS:
  168.     PUSH    DS        ;Set up the
  169.     XOR    AX,AX        ; stack for a
  170.     PUSH    AX        ; return to DOS.
  171.     CALL    GETARGS     ;Process arguments
  172.     CALL    SRCHDIR     ;Search directory
  173.     CMP    SRTFLG,0    ;Check if any sort
  174.     JZ    A1        ; option selected.
  175.     CALL    LNKDIRB     ;Leave in original
  176.     JMP    SHORT A2    ; directory order.
  177. A1:    CALL    SRTDIRB     ;Sort by major key
  178. A2:    CALL    GETFREE     ;Get free space
  179.     CALL    SPLTLST     ;Set up for 2 columns
  180.     CALL    PRTHDNG     ;Print headings
  181.     CALL    PRTDRVR     ;Print detail lines
  182.     CALL    PRTNFLS     ;Print # of files
  183.     RET            ;Return to DOS
  184. MAIN    ENDP
  185.  
  186.     SUBTTL    GETARGS - PROCESS ARGUMENTS
  187.     PAGE
  188. GETARGS PROC    NEAR
  189.     MOV    SI,PARAM_B    ;point to cmd buffer
  190.     MOV    DI,OFFSET DRVNBR ;point to FCB
  191.     MOV    AL, 1111B    ;Select parse options
  192.     DOSCALL @PARSEF     ;Parse filename
  193.     CMP    BYTE PTR [DI],0 ;If <> 0 then
  194.     JNZ    B1        ; not default drive
  195.     DOSCALL @GETDSK     ;AL <- default disk
  196.     INC    AL        ;Increment drive #
  197.     STOSB            ;Save drive #
  198. B1:    MOV    SI,PARAM_L    ;SI <- ptr cmd length
  199.     MOV    CH,0
  200.     MOV    CL,[SI]     ;CL <- # chars in cmd
  201.     JCXZ    B10
  202. B2:    INC    SI        ;Point to next char
  203.     CMP    BYTE PTR [SI],'/'
  204.     JNZ    B8        ;If not a slash
  205.     MOV    AL,[SI+1]    ;AL <- option letter
  206.     AND    AL,0DFH     ;Force to upper-case
  207.     CMP    AL,'A'          ;Hidden & system files?
  208.     JNZ    B3        ;Nope, try next one.
  209.     MOV    BYTE PTR ATTRIB,2+6  ;Hidden & system
  210. B3:    CMP    AL,'E'          ;Without screen erase?
  211.     JNZ    B4        ;Nope, try next one.
  212.     MOV    CLSFLG,AL
  213. B4:    CMP    AL,'S'          ;Sort by size?
  214.     JNZ    B5        ;Nope, try next one.
  215.     MOV    SIZFLG,AL
  216. B5:    CMP    AL,'D'          ;Sort by date/time?
  217.     JNZ    B6        ;Nope, try next one.
  218.     MOV    DTEFLG,AL
  219. B6:    CMP    AL,'X'          ;Sort by extension?
  220.     JNZ    B7        ;Nope, try next one.
  221.     MOV    EXTFLG,AL
  222. B7:    CMP    AL,'N'          ;Original order?
  223.     JNZ    B8        ;Nope, try next one.
  224.     MOV    SRTFLG,AL
  225. B8:    CMP    AL,'P'          ;Pause when screen full?
  226.     JNZ    B9        ;Nope, try next one.
  227.     MOV    PSEFLG,AL
  228. B9:    LOOP    B2        ;Test for another param.
  229. B10:    RET
  230. GETARGS ENDP
  231.  
  232.     SUBTTL    SRCHDIR - SEARCH DIRECTORY
  233.     PAGE
  234. SRCHDIR PROC    NEAR
  235.     DOSCALL @SETDTA,DTA    ;Set DTA for dir. search
  236.     DOSCALL @SRCH1,XFCB    ;First call to search dir.
  237. C1:    OR    AL,AL
  238.     JNZ    C2        ;Not found, quit looking.
  239.     MOV    BX,DIRLNK    ;BX <- base of DIRBUF
  240.     LEA    DI,[BX].NAM
  241.     MOV    SI,OFFSET FILNAME
  242.     MOV    CX,SIZE NAM
  243.     CLD
  244.     REPZ    MOVSB        ;Move filename to DIRBUF
  245.     MOV    BYTE PTR [DI],'.' ; Store a period
  246.     INC    DI
  247.     MOV    CX,SIZE EXT
  248.     REPZ    MOVSB        ;Move ext to DIRBUF
  249.     MOV    SI,OFFSET FILTIME
  250.     MOVSW            ;Move time to DIRBUF
  251.     MOVSW            ;Move date to DIRBUF
  252.     MOV    SI,OFFSET FILSIZE
  253.     MOVSW            ;Move size to DIRBUF
  254.     MOVSW
  255.     ADD    BX,SIZE DIRNTRY ;Point to next entry
  256.     MOV    DIRLNK,BX    ;Save ptr
  257.     INC    NBRFILS     ;Increment file count
  258.     DOSCALL @SRCH2,XFCB    ;Search for next file
  259.     JMP    C1        ;Loop for next one
  260. C2:    RET
  261. SRCHDIR ENDP
  262.  
  263.     SUBTTL    SRTDIRB - SORTS ENTRIES IN DIRBUF
  264.     PAGE
  265. SRTDIRB PROC    NEAR    ;Sorts directory entries in DIRBUF
  266.     MOV    DI,OFFSET DIRBUF ;Point to DIRBUF
  267. D1:    CMP    DI,DIRLNK    ;Are there anymore?
  268.     JNC    D8        ;NO, exit
  269.     MOV    SI,OFFSET C1LNK ;Start with column 1 ptr
  270. D2:    MOV    BX,SI
  271.     MOV    SI,[BX]     ;SI<-ptr to next entry
  272.     OR    SI,SI
  273.     JZ    D7        ;if link=0
  274.     MOV    AX,SI
  275.     MOV    DX,DI
  276.     XOR    CL,CL        ;CL <- 0
  277.     CMP    CL,SIZFLG
  278.     JNZ    D5        ;If sort by size
  279.     CMP    CL,DTEFLG
  280.     JNZ    D4        ;If sort by date/time
  281.     CMP    CL,EXTFLG
  282.     JNZ    D3        ;If sort by ext
  283.     LEA    SI,[SI].NAM
  284.     LEA    DI,[DI].NAM
  285.     MOV    CX,1+SIZE NAM+SIZE EXT    ;# of bytes
  286.     JMP    SHORT D6
  287. D3:    LEA    SI,[SI].EXT    ;Sort by extension
  288.     LEA    DI,[DI].EXT
  289.     MOV    CX,SIZE EXT    ;# of bytes
  290.     JMP    SHORT D6
  291. D4:    LEA    SI,[SI].DTE    ;Sort by date/time
  292.     LEA    DI,[DI].DTE
  293.     MOV    CX,2        ;# of words
  294.     STD
  295.     REPZ    CMPSW
  296.     MOV    DI,DX
  297.     MOV    SI,AX
  298.     JBE    D2
  299.     JMP    SHORT D7
  300. D5:    LEA    SI,[SI].SZH    ;Sort by size
  301.     LEA    DI,[DI].SZH
  302.     MOV    CX,2        ;# of words
  303.     STD
  304.     REPZ    CMPSW
  305.     MOV    DI,DX
  306.     MOV    SI,AX
  307.     JBE    D2
  308.     JMP    SHORT D7
  309. D6:    CLD            ;Sort by name.ext
  310.     REPZ    CMPSB
  311.     MOV    DI,DX
  312.     MOV    SI,AX
  313.     JBE    D2
  314. D7:    MOV    [DI],SI
  315.     MOV    [BX],DI
  316.     ADD    DI,SIZE DIRNTRY ;Point to next entry
  317.     JMP    D1
  318. D8:    RET
  319. SRTDIRB ENDP
  320.  
  321.     SUBTTL
  322.     PAGE
  323. ; LNKDIRB - LINKS ENTRIES IN DIRBUF
  324.  
  325. LNKDIRB PROC    NEAR        ;LINK ENTRIES IN DIRBUF
  326.     MOV    DI,OFFSET DIRBUF
  327.     MOV    C1LNK,DI       ;Point to 1st entry
  328.     MOV    CX,NBRFILS    ;Set loop counter
  329.     DEC    CX
  330. LNK1:    MOV    BX,DI
  331.     ADD    DI,SIZE DIRNTRY ;Offset to next entry
  332.     MOV    [BX],DI     ;Store ptr
  333.     LOOP    LNK1        ;Link next entry
  334.     MOV    [DI],CX     ;Last ptr <- null
  335.     RET
  336. LNKDIRB ENDP
  337.  
  338. ; SPLTLST - SPLITS LINKED LIST IN HALF
  339.  
  340. SPLTLST PROC    NEAR
  341.     MOV    CX,NBRFILS    ;Get # of entries
  342.     SAR    CX,1        ; and divide by 2
  343.     JZ    F2        ;if NBRFILS < 2
  344.     ADC    CL,0        ;Account for odd #
  345.     MOV    BX,OFFSET C1LNK
  346. F1:    MOV    BX,[BX]     ;Chain thru list to
  347.     LOOP    F1        ; last row of column 1.
  348.     MOV    AX,[BX]     ;Get ptr to 1st row of col 2
  349.     MOV    C2LNK,AX    ; C2LNK <- R1,C2 ptr
  350.     MOV    [BX],CX     ;Last row of col 1 <- null
  351. F2:    RET
  352. SPLTLST ENDP
  353.  
  354.     SUBTTL    GETFREE - GET DISK FREE SPACE
  355.     PAGE
  356. GETFREE PROC        NEAR        ;cluster = allocation unit
  357.     MOV     DL,DRVNBR        ;Get drive #
  358.     PUSH    DS            ;Save DS
  359.     DOSCALL @GETVER        ;get DOS version number               JYF
  360.     CMP     AL,2        ;is this version 2.0 or higher?           JYF
  361.     JGE     E4            ;yes                       JYF
  362.                 ;no                        JYF
  363.     DOSCALL @FATAD2        ;Get FAT info from DOS
  364.     MOV     AH,0        ;AL = sector size
  365.     XCHG    CX,DX        ;Sector size times the
  366.     MUL     DX            ; # sectors/cluster
  367.     PUSH    AX            ;Save cluster size
  368.     XOR     AX,AX        ;Unused clusters = 0
  369.     MOV     SI,2        ;Skip first 3 clusters
  370. E1: MOV     DI,SI        ;DI <- cluster #
  371.     SHR     DI,1        ;Divide cluster number
  372.     ADD     DI,SI        ; by 1.5
  373.     MOV     DI,[BX+DI]        ;Fetch from FAT
  374.     TEST    SI,1        ;Test if even or odd
  375.     JZ        E2            ;If even then skip
  376.     SHR     DI,1        ; else if odd
  377.     SHR     DI,1        ;  right justify the
  378.     SHR     DI,1        ;  cluster number.
  379.     SHR     DI,1
  380. E2: AND     DI,0FFFH        ;Mask the low 12 bits
  381.     JNZ     E3            ;If not 0 then skip, else
  382.     INC     AX            ; increment counter.
  383. E3: INC     SI            ;Point to next cluster
  384.     LOOP    E1            ; and go check it.
  385.     POP     CX            ;Get cluster size, times
  386.     MUL     CX            ;  # of free clusters
  387.     JMP     E5            ;skip processing for DOS 2.0        JYF
  388. E4:                ;processing for DOS 2.00            JYF
  389.     DOSCALL @DSKFSP        ;get disk free space            JYF
  390.     MUL     BX            ;AX (sectors/clustor) * BX (free clustors)    JYF
  391.     MOV     DX,AX        ;                        JYF
  392.     MUL     CX            ;AX * CX (bytes/clustor)            JYF
  393. E5:                ;                        JYF
  394.     POP     DS            ;Restore DS
  395.     MOV     LOSIZE,AX        ;Save the 32 bit
  396.     MOV     HISIZE,DX        ; binary free space
  397.     MOV     BX,C1LNK        ;Insert FREESPC in
  398.     MOV     DI,OFFSET FREESPC ;first position
  399.     MOV     [DI],BX        ; of linked list of
  400.     MOV     C1LNK,DI        ; directory entries.
  401.     INC     NBRFILS        ;Bump # of entries
  402.     RET
  403. GETFREE ENDP
  404.  
  405.     SUBTTL  PRTHDNG - PRINT HEADINGS
  406.     PAGE
  407. PRTHDNG PROC        NEAR
  408.     MOV    AL,CLSFLG
  409.     OR    AL,AL
  410.     JNZ    G1        ;If not erase screen
  411.     SUB    CX,CX
  412.     MOV    DX,24*256+79    ;row=24 col=79
  413.     MOV    BH,7        ;Video mode
  414.     MOV    AX,0600H
  415.     INT    10H        ;BIOS video call
  416.     SUB    DX,DX
  417.     MOV    AH,2        ;Clear screen
  418.     MOV    BH,0
  419.     INT    10H        ;BIOS video call
  420. G1:    MOV    AL,DRVNBR    ;Get drive #
  421.     ADD    HDRVE,AL    ;Convert to ascii
  422.     DOSCALL @GETDTE ; CX<-year, DH<-month, DL<-day
  423.     MOV    AL,DH
  424.     AAM
  425.     XCHG    AL,AH
  426.     OR    D_MM,AX     ;Fold into month
  427.     MOV    AL,DL
  428.     AAM
  429.     XCHG    AL,AH
  430.     OR    D_DD,AX     ;Fold into day
  431.     MOV    AX,CX
  432.     SUB    AX,1900
  433.     AAM
  434.     XCHG    AL,AH
  435.     OR    D_YY,AX     ;Fold into year
  436.     DOSCALL @GETTME ; CH<-hours, CL<-minutes
  437.     MOV    AL,CH        ;AL<-binary hours
  438.     AAM            ;Convert AL to two
  439.     XCHG    AL,AH        ; BCD digits in AX.
  440.     OR    T_HH,AX     ;Fold into hours
  441.     MOV    AL,CL        ;AL<-binary minutes
  442.     AAM            ;Convert AL to two
  443.     XCHG    AL,AH        ; BCD digits in AX.
  444.     OR    T_MM,AX     ;Fold into minutes
  445.     DOSCALL @STROUT,HDNG1    ;Print main heading
  446.     DOSCALL @STROUT,HDNG2    ;Print column 1 heading
  447.     CMP    WORD PTR C2LNK,0
  448.     JZ    G2        ;If not 2 columns
  449.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  450.     DOSCALL @STROUT,HDNG2    ;Print column 2 heading
  451. G2:    DOSCALL @STROUT,CRLF    ;Start a new line
  452.     RET
  453. PRTHDNG ENDP
  454.  
  455.     SUBTTL    PRINT DETAIL LINES
  456.     PAGE
  457. PRTDRVR PROC    NEAR        ;Driver routine
  458.     MOV    BX,C1LNK
  459.     OR    BX,BX        ;more to print?
  460.     JZ    H2        ; no, return
  461.     MOV    AX,[BX]
  462.     MOV    C1LNK,AX
  463.     CALL    PRTDTL        ;print column one
  464.     MOV    BX,C2LNK
  465.     OR    BX,BX
  466.     JZ    H1        ;If no column 2 entry
  467.     DOSCALL @STROUT,SPACES-5 ;print 5 spaces
  468.     MOV    AX,[BX]
  469.     MOV    C2LNK,AX
  470.     CALL    PRTDTL        ;print column two
  471. H1:    DOSCALL @STROUT,CRLF
  472.     CMP    PSEFLG,0    ;Check for pause option
  473.     JZ    PRTDRVR     ;Nope, continue
  474.     DEC    LINCNT        ;Decrement line counter
  475.     JNZ    PRTDRVR     ;If page not full?
  476.     MOV    LINCNT,LPERSCR-2 ;Reset to # lines/screen
  477.     DOSCALL @STROUT,PSEMSG    ;Display pause message.
  478.     MOV    AL,@KEYIN    ;Specify input function
  479.     DOSCALL @CKEYIN     ;Wait for key press
  480.     DOSCALL @STROUT,CRLF    ;Set to new line
  481.     JMP    PRTDRVR     ;Go do the next line
  482. H2:    RET
  483. PRTDRVR ENDP
  484.  
  485. PRTDTL    PROC    NEAR    ;Prints file.ext, size, date & time
  486.     MOV    CX,1+SIZE NAM+SIZE EXT
  487.     SUB    DI,DI        ;DI <- 0
  488. I1:    DOSCALL @CHROUT,[BX+DI].NAM
  489.     INC    DI        ;point to next char.
  490.     LOOP    I1        ;go do next char.
  491.     PUSH    BX        ;save entry base
  492.     MOV    SI,[BX].SZL    ;SI <- low size
  493.     MOV    DI,[BX].SZH    ;DI <- high size
  494.     CALL    PRINTDD     ;Print size
  495.     POP    BX        ;restore entry base
  496.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  497.     MOV    AX,[BX].DTE    ;AX <- packed date
  498.     CALL    PRTDTE
  499.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  500.     MOV    AX,[BX].TME    ;AX <- packed time
  501.     CALL    PRTTME
  502.     RET
  503. PRTDTL    ENDP
  504.  
  505.     SUBTTL    PRINTDD - PRINT A DOUBLE WORD IN DI:SI
  506.     PAGE
  507. PRINTDD PROC    NEAR    ;Prints a 32 bit integer in DI:SI
  508.     XOR    AX,AX        ;Zero out the
  509.     MOV    BX,AX        ; working
  510.     MOV    BP,AX        ; registers.
  511.     MOV    CX,32        ;# bits of precision
  512. J1:    SHL    SI,1
  513.     RCL    DI,1
  514.     XCHG    BP,AX
  515.     CALL    J6
  516.     XCHG    BP,AX
  517.     XCHG    BX,AX
  518.     CALL    J6
  519.     XCHG    BX,AX
  520.     ADC    AL,0
  521.     LOOP    J1
  522.     MOV    CX,1710H    ;5904 ?
  523.     MOV    AX,BX
  524.     CALL    J2
  525.     MOV    AX,BP
  526. J2:    PUSH    AX
  527.     MOV    DL,AH
  528.     CALL    J3
  529.     POP    DX
  530. J3:    MOV    DH,DL
  531.     SHR    DL,1        ;Move high
  532.     SHR    DL,1        ; nibble to
  533.     SHR    DL,1        ; the low
  534.     SHR    DL,1        ; position.
  535.     CALL    J4
  536.     MOV    DL,DH
  537. J4:    AND    DL,0FH        ;Mask low nibble
  538.     JZ    J5        ;If not zero
  539.     MOV    CL,0
  540. J5:    DEC    CH
  541.     AND    CL,CH
  542.     OR    DL,'0'          ;Fold in ASCII zero
  543.     SUB    DL,CL
  544.     DOSCALL @CHROUT     ;Print next digit
  545.     RET            ;Exit to caller
  546. PRINTDD ENDP
  547.  
  548. J6    PROC    NEAR
  549.     ADC    AL,AL
  550.     DAA
  551.     XCHG    AL,AH
  552.     ADC    AL,AL
  553.     DAA
  554.     XCHG    AL,AH
  555.     RET
  556. J6    ENDP
  557.  
  558.     SUBTTL    PRINT DATE, TIME & # FILES ROUTINES
  559.     PAGE
  560. PRTDTE    PROC    NEAR    ;Print packed date in AX as MM/DD/YY
  561.     OR    AX,AX
  562.     JNZ    K1        ;If date <> 0
  563.     DOSCALL @STROUT,SPACES-8 ;Print 8 spaces
  564.     RET
  565. K1:    PUSH    AX
  566.     AND    AX,MASK P_MO    ;Mask the month,
  567.     MOV    CL,P_MO     ; set shift count,
  568.     SHR    AX,CL        ; right justify, &
  569.     CALL    PRTBCD        ; print it.
  570.     DOSCALL @CHROUT,'/'
  571.     POP    AX
  572.     PUSH    AX
  573.     AND    AX,MASK P_DY    ;Mask the day &
  574.     CALL    PRTBCD        ; print it.
  575.     DOSCALL @CHROUT,'/'
  576.     POP    AX
  577.     AND    AX,MASK P_YR    ;Mask the year,
  578.     MOV    CL,P_YR     ; set shift count,
  579.     SHR    AX,CL        ; right justify,
  580.     ADD    AX,80        ; add in year bias, &
  581.                 ; print it.
  582. PRTBCD: AAM            ;Convert AL to BCD
  583.     OR    AX,'00'         ;Convert to ASCII
  584.     PUSH    AX
  585.     DOSCALL @CHROUT,AH    ;High order digit
  586.     POP    AX
  587.     DOSCALL @CHROUT,AL    ;Low order digit
  588.     RET
  589. PRTDTE    ENDP
  590.  
  591. PRTTME    PROC    NEAR    ;Print packed time in AX as HH:MM
  592.     OR    AX,AX
  593.     JNZ    L1
  594.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  595.     RET
  596. L1:    PUSH    AX
  597.     AND    AX,MASK P_HR    ;Mask the hours,
  598.     MOV    CL,P_HR     ; set shift count,
  599.     SHR    AX,CL        ; right justify, &
  600.     CALL    PRTBCD        ; print it.
  601.     DOSCALL @CHROUT,':'
  602.     POP    AX
  603.     AND    AX,MASK P_MI    ;Mask the minutes,
  604.     MOV    CL,P_MI     ; set shift count,
  605.     SHR    AX,CL        ; right justify, &
  606.     CALL    PRTBCD        ; print it.
  607.     RET
  608. PRTTME    ENDP
  609.  
  610. PRTNFLS PROC    NEAR    ;print number of files
  611.     MOV    SI,NBRFILS    ;get # of files
  612.     DEC    SI        ;-1 for free space
  613.     XOR    DI,DI        ;zero high order
  614.     CALL    PRINTDD     ;Print # of files
  615.     DOSCALL @STROUT,HDNG3
  616.     RET
  617. PRTNFLS ENDP
  618.     EVEN
  619. DIRBUF    DIRNTRY <>    ;Buffer for directory entries
  620. SDIR    ENDS
  621.     END    MAIN
  622.